package com.freewater.library.lending.dailysheet.eventhandler;

import com.freewater.library.catalogue.model.Book;
import com.freewater.library.catalogue.model.BookRepository;
import com.freewater.library.lending.book.model.event.BookInstanceCheckedOutEvent;
import com.freewater.library.lending.dailysheet.infrastructure.dao.DailyCheckedOutDao;
import com.freewater.library.lending.dailysheet.model.DailyCheckedOutCount;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.Validate;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Optional;

@Component
@RequiredArgsConstructor
public class DailyCheckedOutCountMaterializer {

    private final DailyCheckedOutDao dailyCheckedOutDao;
    private final BookRepository bookRepository;

    @Transactional
    @EventListener(BookInstanceCheckedOutEvent.class)
    public void onEvent(BookInstanceCheckedOutEvent event) {
        String isbn = event.getIsbn();
        LocalDateTime occurAt = event.getOccurAt();
        LocalDate occurAtDay = occurAt.toLocalDate();
        DailyCheckedOutCount.Unique unique = new DailyCheckedOutCount.Unique(isbn, occurAtDay);
        boolean exists = this.dailyCheckedOutDao.existsByUnique(unique);
        if (exists) {
            int rowCount = this.dailyCheckedOutDao.deltaCount(unique, 1);
            Validate.isTrue(rowCount == 1, "增加借出书数量失败，ISBN：%s", isbn);
            return;
        }
        Optional<Book> bookOpt = this.bookRepository.findById(isbn);
        Validate.isTrue(bookOpt.isPresent(), "没有找到对应的书籍，ISBN：%s", isbn);
        Book book = bookOpt.get();
        DailyCheckedOutCount checkedOutCount = new DailyCheckedOutCount(book, occurAtDay);
        this.dailyCheckedOutDao.save(checkedOutCount);
    }
}
